package top.littlejiang.onlinexam.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.littlejiang.onlinexam.common.base.BusinessException;
import top.littlejiang.onlinexam.common.base.Constant;
import top.littlejiang.onlinexam.common.utils.DateUtils;
import top.littlejiang.onlinexam.common.utils.JWTUtils;
import top.littlejiang.onlinexam.common.utils.UUIDUtil;
import top.littlejiang.onlinexam.entity.OlexamExam;
import top.littlejiang.onlinexam.entity.OlexamExamWork;
import top.littlejiang.onlinexam.entity.OlexamTask;
import top.littlejiang.onlinexam.service.*;
import top.littlejiang.onlinexam.vo.ExamAddVO;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @author chen
 * @Description
 * @since 2021/3/31 20:12
 */
@Service
public class OlexamTransServiceImpl implements OlexamTransService {

    @Autowired
    OlexamExamService examService;
    @Autowired
    OlexamCourseService courseService;
    @Autowired
    OlexamExamWorkService workService;
    @Autowired
    OlexamExamPaperService paperService;
    @Autowired
    OlexamTaskService taskService;


    /**
     * 新增考试数据
     *
     * @param examAddVO
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addExam(ExamAddVO examAddVO) throws InstantiationException, IllegalAccessException {
        String examUuid = UUIDUtil.getUUID();
        List<OlexamExamWork> workList = new ArrayList<>();

        examAddVO.getProctorList().stream().forEach(item->{
            OlexamExamWork work = new OlexamExamWork();
            work.setCreateTime(DateUtils.getTime());
            work.setFkExamUuid(examUuid);
            work.setUpdateTime(DateUtils.getTime());
            work.setWorkType("2");
            work.setFkUserId(item.getId());
            work.setFkUserName(item.getUserName());
            workList.add(work);
        });

        examAddVO.getExaminerList().stream().forEach(item->{
            OlexamExamWork work = new OlexamExamWork();
            work.setCreateTime(DateUtils.getTime());
            work.setFkExamUuid(examUuid);
            work.setUpdateTime(DateUtils.getTime());
            work.setWorkType("1");
            work.setFkUserId(item.getId());
            work.setFkUserName(item.getUserName());
            workList.add(work);
        });

        List<OlexamExam> examList = new ArrayList<>();
        OlexamExam modelExam = examAddVO.getExam();
        examAddVO.getClasses().stream().forEach(item->{
            List<Serializable> ids = courseService.getIdsByClass(item, modelExam.getFkCourseName());
            if (ids.size() > 1){
                throw new BusinessException("该班级对应课程数据重复，请联系管理员！");
            }
            OlexamExam exam = new OlexamExam();
            exam.setFkCourseId((Integer)ids.get(0));
            exam.setBeginTime(modelExam.getBeginTime());
            exam.setEndTime(modelExam.getEndTime());
            exam.setExamUuid(examUuid);
            exam.setCreateTime(DateUtils.getTime());
            exam.setUpdateTime(DateUtils.getTime());
            exam.setCreateUser(JWTUtils.getUserId());
            exam.setExamName(modelExam.getExamName());
            exam.setIsAfewRandow(0);
            exam.setStatus(0);
            exam.setRemarks(modelExam.getRemarks());
            examList.add(exam);
        });

        OlexamTask beginTask = new OlexamTask()
                .setFkId(examUuid)
                .setTaskCorn(DateUtils.toCornString(examAddVO.getExam().getBeginTime()))
                .setTaskType(Constant.OPEN_EXAM_HANDLER);
        OlexamTask endTask = new OlexamTask()
                .setFkId(examUuid)
                .setTaskCorn(DateUtils.toCornString(examAddVO.getExam().getEndTime()))
                .setTaskType(Constant.END_EXAM_HANDLER);

        taskService.addTask(beginTask);
        taskService.addTask(endTask);

        workService.saveBatch(workList);
        examService.saveBatch(examList);
    }

    /**
     * 删除考试及对应工作表
     *
     * @param uuids
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteExam(List<String> uuids) {
        uuids.stream().forEach(item -> {
            List<Serializable> taskIds = taskService.selectIdByfk(item);
            taskIds.stream().forEach(taskId -> {
                taskService.deleteTask((String)taskId);
            });
            taskService.deleteById(taskIds);
        });
        workService.deleteByUuid(uuids);
        paperService.deleteByUuid(uuids);
        examService.deleteByUuid(uuids);
    }

    /**
     * 更新
     *
     * @param exam
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateExam(OlexamExam exam) {
        UpdateWrapper wrapper = new UpdateWrapper();
        wrapper.set("begin_time", exam.getBeginTime());
        wrapper.set("end_time", exam.getEndTime());
        wrapper.set("update_time", DateUtils.getTime());
        wrapper.set("remarks", exam.getRemarks());
        wrapper.eq("exam_uuid", exam.getExamUuid());
        examService.update(wrapper);

        List<OlexamTask> tasks = taskService.selectByfk(exam.getExamUuid());

        tasks.stream().forEach(task -> {
            if (task.getTaskType().equals(Constant.OPEN_EXAM_HANDLER)){
                task.setTaskCorn(DateUtils.toCornString(exam.getBeginTime()));
                try {
                    taskService.updateTask(task);
                } catch (Exception e) {
                    throw new BusinessException("任务添加失败！请联系管理员");
                }
            } else if (task.getTaskType().equals(Constant.END_EXAM_HANDLER)){
                task.setTaskCorn(DateUtils.toCornString(exam.getEndTime()));
                try {
                    taskService.updateTask(task);
                } catch (Exception e) {
                    throw new BusinessException("任务添加失败！请联系管理员");
                }
            }

        });
    }
}
